/*
 * @Author: zhangchaosen
 * @Date: 2024-05-20 09:29:53
 * @LastEditors: zhangchaosen
 * @LastEditTime: 2024-05-20 14:16:25
 * @Description:
 */
import { defineStore } from 'pinia'
import { type RouteRecordRaw } from 'vue-router'

import store from '@/store'
import { constantRoutes, asyncRoutes } from '@/router'
import routeSettings from '@/config/route'
import { filterRouters, generateMenus } from '@/utils/route'

/**
 * 使用 meta.roles 确定当前用户是否具有权限
 * @param roles
 * @param route
 */
const hasPermission = (roles: string[], route: RouteRecordRaw) => {
  const routeRoles = route.meta?.roles
  return routeRoles ? roles.some(role => routeRoles.includes(role)) : true
}

/**
 * 通过递归过滤异步路由表
 * @param routes asyncRoutes
 * @param roles
 */
const filterAsyncRoutes = (routes: RouteRecordRaw[], roles: string[]) => {
  const res: RouteRecordRaw[] = []
  routes.forEach(route => {
    const tempRoute = { ...route }
    if (hasPermission(roles, tempRoute)) {
      if (tempRoute.children) {
        tempRoute.children = filterAsyncRoutes(tempRoute.children, roles)
      }
      res.push(tempRoute)
    }
  })
  return res
}

/**
 * 拿到菜单路由列表
 * @param routes 所有路由
 * @returns
 */
const filterMenuRoutes = (routes: RouteRecordRaw[]): RouteRecordRaw[] => {
  const filterRoutes = filterRouters(routes)
  return generateMenus(filterRoutes).filter(item => !item.meta?.hidden)
}

interface State {
  // 路由
  routes: RouteRecordRaw[]
  // 动态路由
  dynamicRoutes: RouteRecordRaw[]
  // 菜单路由
  menuRoutes: RouteRecordRaw[]
}

export const usePermissionStore = defineStore({
  id: 'geek-permission',
  state: (): State => ({
    routes: [...constantRoutes],
    dynamicRoutes: [],
    menuRoutes: []
  }),
  actions: {
    /**
     * 根据角色来区分
     * @param roles
     */
    setRoutes(roles: string[]) {
      // 必须得展开，不然退出登录后再次登录，使用的是同一个对象，
      // 下方的push方法会一直往同一个数组中添加 404路由
      const routes: RouteRecordRaw[] = [...asyncRoutes]

      // 动态路由
      const accessedRoutes = routeSettings.async ? filterAsyncRoutes(routes, roles) : routes
      this.routes = [...constantRoutes.concat([...accessedRoutes])]
      this.dynamicRoutes = [...accessedRoutes]
      this.menuRoutes = filterMenuRoutes(this.routes)
    }
  }
})

/** 在 setup 外使用 */
export function usePermissionStoreHook() {
  return usePermissionStore(store)
}
